package com.xunhang.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xunhang.dto.DeepSeekRequest;
import com.xunhang.dto.DeepSeekResponse;
import com.xunhang.entity.News;
import com.xunhang.exception.AIServiceException;
import com.xunhang.repository.NewsRepository;
import com.xunhang.service.AIService;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

@Service
public class AIServiceImpl implements AIService {

    private static final Logger logger = LoggerFactory.getLogger(AIServiceImpl.class);

    @Value("${deepseek.api.key}")
    private String apiKey;

    @Value("${deepseek.api.url}")
    private String apiUrl;

    @Autowired
    private NewsRepository newsRepository;

    private final ObjectMapper objectMapper = new ObjectMapper();

    private static final int MAX_RETRIES = 3;
    private static final int TIMEOUT = 30000; // 30秒超时

    @Override
    @Transactional
    public void generateAndSaveSummary(News news) {
        if (news == null || news.getDetail() == null || news.getDetail().isEmpty()) {
            logger.warn("无法为空的新闻或没有内容的新闻生成摘要");
            return;
        }

        int retryCount = 0;
        while (retryCount < MAX_RETRIES) {
            try {
                System.out.println("开始生成摘要111");
                String summary = tryGenerateSummary(news.getDetail());
                System.out.println("开始生成摘要222");
                if (summary != null && !summary.isEmpty()) {
                    news.setSummary(summary.trim());
                    newsRepository.save(news);
                    logger.info("成功为新闻[{}]生成并保存摘要", news.getTitle());
                } else {
                    logger.warn("生成的摘要为空，新闻ID: {}", news.getId());
                }
                return;
            } catch (Exception e) {
                retryCount++;
                logger.warn("DeepSeek API调用失败，重试 {}/{}，新闻ID: {}", retryCount, MAX_RETRIES, news.getId(), e);
                if (retryCount >= MAX_RETRIES) {
                    throw new AIServiceException("生成摘要失败，已达到最大重试次数，新闻ID: " + news.getId(), e);
                }
                try {
                    Thread.sleep(1000 * retryCount); // 指数退避
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new AIServiceException("生成摘要被中断，新闻ID: " + news.getId(), ie);
                }
            }
        }
    }

    private String tryGenerateSummary(String content) {
        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(RequestConfig.custom()
                        .setConnectTimeout(TIMEOUT)
                        .setConnectionRequestTimeout(TIMEOUT)
                        .setSocketTimeout(TIMEOUT)
                        .build())
                .build()) {

            // 截取前2000个字符，避免内容过长
            String truncatedContent = content.length() > 2000 ? content.substring(0, 2000) : content;
            System.out.println("准备生成摘要，内容长度: " + truncatedContent.length());

            String prompt = "请为以下新闻内容生成一个简短的摘要（50-100字）：\n" + truncatedContent;

            DeepSeekRequest.Message message = new DeepSeekRequest.Message("user", prompt);
            DeepSeekRequest request = new DeepSeekRequest("deepseek-chat", Collections.singletonList(message));

            // 打印请求体用于调试
            String requestBody = objectMapper.writeValueAsString(request);
            System.out.println("请求体内容: " + requestBody);

            HttpPost httpPost = new HttpPost(apiUrl);
            httpPost.setHeader("Content-Type", "application/json");
            httpPost.setHeader("Authorization", "Bearer " + apiKey);
            httpPost.setHeader("Accept", "application/json");

            httpPost.setEntity(new StringEntity(requestBody, "UTF-8"));

            System.out.println("准备发送请求到: " + apiUrl);
            System.out.println("使用API Key: " + (apiKey != null ? "已设置" : "未设置"));

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                HttpEntity entity = response.getEntity();
                String responseString = EntityUtils.toString(entity);

                System.out.println("API响应状态码: " + statusCode);
                System.out.println("API响应内容: " + responseString);

                if (statusCode >= 200 && statusCode < 300) {
                    DeepSeekResponse deepSeekResponse = objectMapper.readValue(responseString, DeepSeekResponse.class);
                    String result = deepSeekResponse.getContent();
                    if (result == null || result.isEmpty()) {
                        System.out.println("DeepSeek API返回空内容");
                        throw new AIServiceException("DeepSeek API返回空内容");
                    }
                    System.out.println("成功获取摘要: " + result.trim());
                    return result.trim();
                } else {
                    String errorMsg = "DeepSeek API调用失败，状态码: " + statusCode + "，响应: " + responseString;
                    System.out.println(errorMsg);
                    throw new AIServiceException(errorMsg);
                }
            }
        } catch (IOException e) {
            System.out.println("IO异常: " + e.getClass().getName() + ": " + e.getMessage());
            if (e instanceof java.net.ConnectException) {
                System.out.println("无法连接到DeepSeek API服务器，请检查网络");
            } else if (e instanceof java.net.SocketTimeoutException) {
                System.out.println("连接DeepSeek API超时，请检查网络或增加超时时间");
            }
            throw new AIServiceException("调用DeepSeek API时发生IO异常: " + e.getMessage(), e);
        } catch (Exception e) {
            System.out.println("其他异常: " + e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
            throw new AIServiceException("调用DeepSeek API时发生异常: " + e.getMessage(), e);
        }
    }

    @Override
    public void generateSummariesForExistingNews() {
        List<News> newsWithoutSummaries = newsRepository.findBySummaryIsNull();
        for (News news : newsWithoutSummaries) {
            try {
                generateAndSaveSummary(news);
            } catch (AIServiceException e) {
                System.err.println("[ERROR] 为新闻生成摘要失败: " + news.getId() + " - " + e.getMessage());
            }
        }
    }
}